package au.edu.adelaide.mips_soft_core.board_interface_pc.ui;

import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;

import au.edu.adelaide.mips_soft_core.board_interface_pc.core.Core;
import au.edu.adelaide.mips_soft_core.board_interface_pc.core.Device;
import au.edu.adelaide.mips_soft_core.board_interface_pc.core.Device.BoardMode;
import au.edu.adelaide.mips_soft_core.board_interface_pc.core.DeviceListener;

public class UI extends JFrame implements MouseListener, DeviceListener{
	
	JComboBox<Device> deviceSelector = new JComboBox<Device>();
	JButton  deviceConnect = new JButton("Connect");
	JButton deviceDisconnect = new JButton("Disconnect");
	JComboBox<Device.BoardMode> modeChanger = new JComboBox<Device.BoardMode>();
	
	InfoPanel infoPanel = new InfoPanel(this);
	UploadMemoryPanel uploadMemoryPanel = new UploadMemoryPanel(this);
	DownloadMemoryPanel downloadMemoryPanel = new DownloadMemoryPanel(this);
	DebuggerPanel debuggerPanel = new DebuggerPanel(this);
	
	LoggerPanel loggerPanel = new LoggerPanel();
	
	Device connectedDevice = null;
	
	public UI(){
		super("Board Interface - PC");
		JPanel topPanel = new JPanel();
		this.add(topPanel, BorderLayout.NORTH);
		JTabbedPane tabPanel = new JTabbedPane();
		JSplitPane splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tabPanel, loggerPanel);
		
		this.add(splitter, BorderLayout.CENTER);
		
		tabPanel.addTab("Configuration - Info", new JScrollPane(infoPanel));
		tabPanel.addTab("Upload to Board", this.uploadMemoryPanel);
		tabPanel.addTab("Download from Board", this.downloadMemoryPanel);
		tabPanel.addTab("Debugger", this.debuggerPanel);
		
		splitter.setDividerLocation(0.7);
		//building top panel
		{
			refreshDeviceList();
			addComponent(topPanel, deviceSelector, 0, 0);
			addComponent(topPanel, deviceConnect, 1, 0);
			addComponent(topPanel, deviceDisconnect, 2, 0);
			addComponent(topPanel, new JLabel("Board Mode:"), 3, 0);
			addComponent(topPanel, modeChanger, 4, 0);
		}
		
		{
			this.modeChanger.addItem(BoardMode.DOWNLOAD_MODE);
			this.modeChanger.addItem(BoardMode.BOARD_MEMORY_VIEWER);
			this.modeChanger.addItem(BoardMode.DEBUGER);
			this.modeChanger.addItem(BoardMode.RUN);
			this.modeChanger.setSelectedItem(BoardMode.DOWNLOAD_MODE);
			
		}
		
		this.deviceDisconnect.setEnabled(false);
		this.deviceConnect.addMouseListener(this);
		this.deviceDisconnect.addMouseListener(this);
		this.modeChanger.addItemListener(new ItemListener(){

			@Override
			public void itemStateChanged(ItemEvent event) {
				if(event.getStateChange() == ItemEvent.SELECTED){
					connectedDevice.changeBoardMode((BoardMode)modeChanger.getSelectedItem());
				}
			}
			
		});
		
	}
	
	public void refreshDeviceList(){
		this.deviceSelector.removeAllItems();
		Core.getCore().refreshDeviceList();
		for(int i = 0; i < Core.getCore().getNumberOfDevices(); i++){
			this.deviceSelector.addItem(Core.getCore().getDevice(i));
		}
	}
	
	public static void addComponent(JPanel panel, JComponent component, int x, int y){
		panel.add(component);
	}
	
	
	

	@Override
	public void mouseClicked(MouseEvent event) {
		if(event.getSource() == this.deviceConnect){
			connectToSelectedDevice();
		}else if(event.getSource() == this.deviceDisconnect){
			disconnectSelectedDevice();
		}
	}
	
	public void connectToSelectedDevice(){
		this.deviceConnect.setEnabled(false);
		Device device = (Device) this.deviceSelector.getSelectedItem();
		this.connectedDevice = device;
		device.addDeviceListener(this);
		try {
			device.connect();
			device.downloadInfo();
			//this.infoPanel.updatePanel();
			//this.uploadMemoryPanel.updatePanel();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.deviceDisconnect.setEnabled(true);
	}
	
	public void disconnectSelectedDevice() {
		this.deviceDisconnect.setEnabled(false);
		try {
			this.connectedDevice.disconnect();
			this.connectedDevice = null;
			this.infoPanel.updatePanel();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		this.deviceConnect.setEnabled(true);
	}

	@Override
	public void mousePressed(MouseEvent e) {}

	@Override
	public void mouseReleased(MouseEvent e) {}

	@Override
	public void mouseEntered(MouseEvent e) {}

	@Override
	public void mouseExited(MouseEvent e) {}
	
	public static void main(String[] args){
		UI ui = new UI();
		BufferedImage bi;
		try {
			bi = ImageIO.read(UI.class.getResourceAsStream("AdelaideUniLogo.jpg"));
			ui.setIconImage(new ImageIcon(bi).getImage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		ui.setSize(700, 700);
		ui.setVisible(true);
		ui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	@Override
	public void error(String message) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void statusChanged() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void boardDiagnosed() {
		this.infoPanel.updatePanel();
		this.uploadMemoryPanel.updatePanel();
		for(int i = 0; i < this.connectedDevice.getNumberOfProcessor(); i++){
			this.debuggerPanel.addProcessor(this.connectedDevice.getProcessor(i));
		}
	}

	@Override
	public void deviceFileUploadedFinished(int memoryModule,
			TaskCompletionStatus status, String message) {
		// TODO Auto-generated method stub
		
	}

}
